#include "log.h"
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/support/date_time.hpp>
#include <iostream>
#include <locale>

// 定义静态变量
std::mutex GlobalLog::s_log_mutex;
std::shared_ptr<GlobalLog> GlobalLog::s_global_log;



std::shared_ptr<GlobalLog> GlobalLog::getGlobalLog() {
    if (!s_global_log) {
        s_global_log = std::make_shared<GlobalLog>();
    }
    return s_global_log;
}

// 将我们的日志级别映射到Boost.Log级别
boost::log::trivial::severity_level MapLogLevel(GlobalLogLevel level) {
    switch (level) {
        case GlobalLogLevel_Debug: return boost::log::trivial::debug;
        case GlobalLogLevel_Info: return boost::log::trivial::info;
        case GlobalLogLevel_Warning: return boost::log::trivial::warning;
        case GlobalLogLevel_Error: return boost::log::trivial::error;
        case GlobalLogLevel_Fatal: return boost::log::trivial::fatal;
        default: return boost::log::trivial::info;
    }
}

GlobalLog::GlobalLog() : m_initialized(false) {
}

GlobalLog::~GlobalLog() {
    // if (m_initialized) {
    //     boost::log::core::get()->flush();
    // }
}

void GlobalLog::Init(GlobalLogLevel level, const std::string& log_file) {
    std::lock_guard<std::mutex> lock(s_log_mutex);
    
    if (m_initialized) {
        return; // 已经初始化过了
    }
    
    try {
        // 设置UTF-8编码支持
        std::locale::global(std::locale(""));
        
        // 添加通用属性
        boost::log::add_common_attributes();
        
        // 设置控制台输出格式，支持UTF-8
        boost::log::add_console_log(
            std::cout, 
            boost::log::keywords::format = "[%TimeStamp%] [%Severity%] %Message%",
            boost::log::keywords::auto_flush = true
        );
        
        // 设置文件输出
        if (!log_file.empty()) {
            boost::log::add_file_log(
                boost::log::keywords::file_name = log_file + "_%N.log",
                boost::log::keywords::rotation_size = 10 * 1024 * 1024, // 10MB
                boost::log::keywords::max_size = 100 * 1024 * 1024,     // 100MB
                boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point(0, 0, 0),
                boost::log::keywords::format = "[%TimeStamp%] [%Severity%] [%ThreadID%] %Message%",
                boost::log::keywords::auto_flush = true
            );
        }
        
        // 设置日志级别过滤器
        boost::log::core::get()->set_filter(
            boost::log::trivial::severity >= MapLogLevel(level)
        );
        
        m_initialized = true;
        m_log_level = level;
        
        // 记录初始化成功
        BOOST_LOG_TRIVIAL(info) << "Log system initialized successfully. Level: " << level 
                                << ", File: " << (log_file.empty() ? "console only" : log_file);
    }
    catch (const std::exception& e) {
        std::cerr << "Failed to initialize log system: " << e.what() << std::endl;
        throw;
    }
}

void GlobalLog::Log(GlobalLogLevel level, const std::string& message, bool flush) {
    if (!m_initialized) {
        std::cerr << "Log system not initialized!" << std::endl;
        return;
    }
    
    try {
        switch (level) {
            case GlobalLogLevel_Debug:
                BOOST_LOG_TRIVIAL(debug) << message;
                break;
            case GlobalLogLevel_Info:
                BOOST_LOG_TRIVIAL(info) << message;
                break;
            case GlobalLogLevel_Warning:
                BOOST_LOG_TRIVIAL(warning) << message;
                break;
            case GlobalLogLevel_Error:
                BOOST_LOG_TRIVIAL(error) << message;
                break;
            case GlobalLogLevel_Fatal:
                BOOST_LOG_TRIVIAL(fatal) << message;
                break;
            default:
                BOOST_LOG_TRIVIAL(info) << message;
                break;
        }
        if (flush) {
            boost::log::core::get()->flush();
        }
    }
    catch (const std::exception& e) {
        std::cerr << "Log error: " << e.what() << std::endl;
    }
}

void GlobalLog::LogDebug(const std::string& message, bool flush) {
    Log(GlobalLogLevel_Debug, message, flush);
}

void GlobalLog::LogInfo(const std::string& message, bool flush) {
    Log(GlobalLogLevel_Info, message, flush);
}

void GlobalLog::LogWarning(const std::string& message, bool flush) {
    Log(GlobalLogLevel_Warning, message, flush);
}

void GlobalLog::LogError(const std::string& message, bool flush) {
    Log(GlobalLogLevel_Error, message, flush);
}

void GlobalLog::LogFatal(const std::string& message, bool flush) {
    Log(GlobalLogLevel_Fatal, message, flush);
}

